package org.zhangyp.n04design.n01SingletonPattern;

/**
 * 需单例创建的目标类
 *
 * @author ypzhang
 * @since 2025/6/19
 */
public class Singleton {
    public void doMethod() {
        System.out.println("做了一些事情");
    }


    private static Singleton uniqueInstance;

    /**
     * 懒汉式-线程不安全
     * 在多线程的情况下可能会多次实例化
     *
     * @return
     */
    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }

    /**
     * 同步锁-线程安全
     * 当一个线程进入该方法后，其他线程都必须等待，因此性能上有一定的损耗
     *
     * @return
     */
    public static synchronized Singleton getSyncUniqueInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }

    private volatile static Singleton volatileUniqueInstance;

    /**
     * 双重校验锁-线程安全
     * 加锁操作只需要对实例化那部分的代码进行，只有当 uniqueInstance 没有被实例化时，才需要进行加锁。
     * 双重校验锁先判断 uniqueInstance 是否已经被实例化，如果没有被实例化，那么才对实例化语句进行加锁。
     *
     * @return
     */
    public static Singleton getDoubleSyncUniqueInstance() {
        if (volatileUniqueInstance == null) {
            synchronized (Singleton.class) {
                if (volatileUniqueInstance == null) {
                    volatileUniqueInstance = new Singleton();
                }
            }
        }
        return volatileUniqueInstance;
    }

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    /**
     * 静态内部类-线程安全
     * 静态内部类在类加载的时候不会被加载，只有当调用 getHolderUniqueInstance 方法时，才会加载静态内部类
     * 这种方式不仅具有延迟初始化的好处，而且由虚拟机提供了对线程安全的支持
     *
     * @return
     */
    public static Singleton getHolderUniqueInstance() {
        return SingletonHolder.INSTANCE;
    }


}
